package com.lancoo.ccas53.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lancoo.ccas53.arrangecourse.dataprocess.GenerateSchedulingData;
import com.lancoo.ccas53.arrangecourse.dataprocess.GenerateSplitClassGroup;
import com.lancoo.ccas53.arrangecourse.entities.TeachingClassUnit;
import com.lancoo.ccas53.entity.SubClassGroup;
import com.lancoo.ccas53.entity.SubClassGroupTemp;
import com.lancoo.ccas53.exception.BizException;
import com.lancoo.ccas53.mapper.SubClassGroupMapper;
import com.lancoo.ccas53.pojo.dto.ArrangeTeachingClassDto;
import com.lancoo.ccas53.pojo.vo.SubGroupVo;
import com.lancoo.ccas53.service.SubClassGroupService;
import com.lancoo.ccas53.service.SubClassGroupTempService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 分班教学班对应的分组 服务实现类
 * </p>
 *
 * @author quin.song
 * @since 2024-05-20
 */
@Service
public class SubClassGroupServiceImpl extends ServiceImpl<SubClassGroupMapper, SubClassGroup> implements SubClassGroupService {

    @Resource
    private SubClassGroupTempService subClassGroupTempService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<SubGroupVo> autoGroup(Integer taskId, String uniqueShiftSign) {
        List<SubGroupVo> res = new ArrayList<>();
        LinkedList<TeachingClassUnit> teachingClassUnits = getTeachingClassUnits(taskId, uniqueShiftSign);
        if (CollUtil.isNotEmpty(teachingClassUnits)) {
            GenerateSplitClassGroup splitClassGroup = new GenerateSplitClassGroup();
            LinkedList<TeachingClassUnit> groupedList = splitClassGroup.start(teachingClassUnits);
            Map<String, LinkedList<TeachingClassUnit>> groupedUnitMap = groupedList.stream()
                    .collect(Collectors.groupingBy(TeachingClassUnit::getSplitClassGroupId, Collectors.toCollection(LinkedList::new)));

            List<SubClassGroup> saveGroups = new ArrayList<>();
            List<String> nameList = new ArrayList<>();
            for (Map.Entry<String, LinkedList<TeachingClassUnit>> entry : groupedUnitMap.entrySet()) {
                LinkedList<TeachingClassUnit> groupedTeachingClassList = entry.getValue();
                String subGroupId = entry.getKey();
                String subGroupName = groupedTeachingClassList.stream()
                        .map(TeachingClassUnit::getCourseName)
                        .collect(Collectors.joining()) + "上课组";

                int i = 1;
                while (nameList.contains(subGroupName + i)) {
                    i++;
                }
                subGroupName = subGroupName + i;
                nameList.add(subGroupName);
                SubGroupVo subGroupVo = new SubGroupVo();
                subGroupVo.setUniqueGroupSign(subGroupId);
                subGroupVo.setGroupName(subGroupName);
                subGroupVo.setWeekNum(1);

                for (TeachingClassUnit teachingClassUnit : groupedTeachingClassList) {
                    SubClassGroup subgroupEntity = new SubClassGroup();
                    BeanUtils.copyProperties(teachingClassUnit, subgroupEntity);
                    subgroupEntity.setHourType(String.valueOf(teachingClassUnit.getTeachingType()));
                    subgroupEntity.setUniqueGroupSign(subGroupId);
                    subgroupEntity.setGroupName(subGroupName);
                    saveGroups.add(subgroupEntity);

                    List<SubClassGroup> subGroupList = subGroupVo.getSubGroupTemps() == null ?
                            new ArrayList<>() : subGroupVo.getSubGroups();
                    subGroupList.add(subgroupEntity);
                    subGroupVo.setSubGroups(subGroupList);
                }

                res.add(subGroupVo);
            }

            List<SubClassGroup> subClassGroups = BeanUtil.copyToList(saveGroups, SubClassGroup.class);
            if (CollUtil.isNotEmpty(saveGroups)) {
                this.lambdaUpdate().eq(SubClassGroup::getUniqueShiftSign,uniqueShiftSign).remove();
                this.saveBatch(subClassGroups);
            }
        }
        res.sort(Comparator.comparing(SubGroupVo::getGroupName));
        return res;
    }

    @Override
    public String confirmGroup(Integer taskId, String uuid) {
        List<SubClassGroupTemp> teachingClassSubGroupTemps = subClassGroupTempService.lambdaQuery()
                .eq(SubClassGroupTemp::getTaskId, taskId).eq(SubClassGroupTemp::getUniqueShiftSign, uuid)
                .list();
        List<SubClassGroupTemp> unassignedGroup = teachingClassSubGroupTemps.stream().filter(p -> StringUtils.isBlank(p.getUniqueGroupSign())).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(unassignedGroup)) {
            throw new BizException("还存在课程未进行分配,请分配后在点击确认");
        }

        List<SubClassGroup> subClassGroupList = new ArrayList<>();
        teachingClassSubGroupTemps.forEach(o -> {
            SubClassGroup subClassGroup = new SubClassGroup();
            subClassGroup.setTaskId(taskId);
            subClassGroup.setUniqueGroupSign(o.getUniqueGroupSign());
            subClassGroup.setGroupName(o.getGroupName());
            subClassGroup.setWeekNum(o.getWeekNum());
            subClassGroup.setTeachingClassId(o.getTeachingClassId());
            subClassGroup.setTeachingClassName(o.getTeachingClassName());
            subClassGroup.setCourseId(o.getCourseId());
            subClassGroup.setHourType(o.getHourType());
            subClassGroup.setUniqueShiftSign(o.getUniqueShiftSign());
            subClassGroup.setIsSingle(o.getIsSingle());
            subClassGroupList.add(subClassGroup);
        });
        subClassGroupTempService.removeBatchByIds(teachingClassSubGroupTemps);
        this.saveOrUpdateBatch(subClassGroupList);
        return "分组确认成功";
    }

    private LinkedList<TeachingClassUnit> getTeachingClassUnits(Integer taskId, String uniqueShiftSign) {
        List<ArrangeTeachingClassDto> teachingClassList = baseMapper.getSubTeachingClass(taskId, uniqueShiftSign);
        GenerateSchedulingData generateSchedulingData = new GenerateSchedulingData();
        return generateSchedulingData.convertToSplitTeachingClassUnit(taskId, teachingClassList, 0);
    }
}
